/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package nx2.arbitrators;

import nx2.utils.*;
import nx2.behaviors.*;
import java.util.*;
/**
 *
 * @author alejo
 */
public class GArbitrator extends Arbitrator{

    public GArbitrator(String name)
    {
        super(name);
        
    }
    
    @Override
    public Vector2D value()
    {
        Vector2D [] values = new Vector2D[this.behaviors.size()];

        //output of the arbitrator
        Vector2D total = new Vector2D(0f,0f,0);

        //partial sum of vectors with the same priorities
        Vector2D partial = new Vector2D(0f,0f,0);

        //defines if the output channel is full(=1) or not (<1)
        int outputUse = 0;

        //partial outputUse of the channel
        int partialOutputUse = 0;

        //number of behaviors with the same priority
        int samePriorCount = 1;

        //sort behaviors according to their priorities
        Comparator r = Collections.reverseOrder();
        Collections.sort(behaviors,r);


        for(int i=0;i<this.behaviors.size();i++){


            NxBehavior behavior = (NxBehavior)behaviors.get(i);

            int b1Prior = behavior.getPriority();

            NxBehavior nextBehavior;
            int b2Prior = 0;

            if(i+1 < this.behaviors.size())
            {
                nextBehavior = (NxBehavior)behaviors.get(i+1);
                b2Prior = nextBehavior.getPriority();
            }

            //first check if behavior is enabled
            if(behavior.enabled)
            {

                //first check if output is not full
                if(outputUse >= 1)
                    break;

                //then check if this is the only behavior with this priority
                if(b2Prior<b1Prior)
                {
                    if(samePriorCount>1)
                    {
                        partial = partial.add(((Vector2D)behavior.value()).scale(behavior.getGain()));

                        partial = partial.scale((1.0f/samePriorCount));
                        total = total.add(partial);
                        
                        partialOutputUse /= samePriorCount;
                        outputUse += partialOutputUse;

                        //reset partial values
                        samePriorCount = 1;
                        partialOutputUse = 0;
                        partial = new Vector2D(0,0,Vector2D.MODE_XY);

                    }
                    else
                    {
                        //sum the vectorr to the output and increment output use
                        total = total.add(((Vector2D)behavior.value()).scale(behavior.getGain()));

                        outputUse += behavior.getGain();
                    }

                }
                else
                {
                    partial = partial.add(((Vector2D)behavior.value()).scale(behavior.getGain()));
                    partialOutputUse += behavior.getGain();

                    samePriorCount++;

                }
            }
        }

        if(this.enabled)
            return total;
        else
            return new Vector2D();
    }
}
